package com.xbongbong.paas.lowcode.impl;

import com.alibaba.fastjson.JSON;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.lowcode.DeveloperService;
import com.xbongbong.paas.lowcode.LowCodeConfigService;
import com.xbongbong.paas.lowcode.LowCodeJsFileService;
import com.xbongbong.paas.model.LowCodeJsFileModel;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.pro.domain.entity.LowCodeJsFileEntity;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.lowcodeconfig.pojo.dto.LowCodeConfigGetDTO;
import com.xbongbong.pro.lowcodeconfig.pojo.vo.LowCodeConfigGetVO;
import com.xbongbong.pro.lowcodejsfile.pojo.JsFilePojo;
import com.xbongbong.pro.lowcodejsfile.pojo.dto.LowCodeJsFileGetDTO;
import com.xbongbong.pro.lowcodejsfile.pojo.dto.LowCodeJsFileSaveDTO;
import com.xbongbong.pro.lowcodejsfile.pojo.vo.LowCodeJsFileGetVO;
import com.xbongbong.pro.lowcodejsfile.pojo.vo.LowCodeJsFileSaveVO;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.sys.help.ProPermissionHelp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2021/03/10 9:52
 */
@Service("lowCodeJsFileService")
public class LowCodeJsFileServiceImpl implements LowCodeJsFileService {

    private static final Logger LOG = LoggerFactory.getLogger(LowCodeJsFileServiceImpl.class);

    @Resource
    private LowCodeJsFileModel lowCodeJsFileModel;
    @Resource
    private DeveloperService developerService;
    @Resource
    private LowCodeConfigService lowCodeConfigService;
    @Resource
    private MongoLogHelp mongoLogHelp;

    @Override
    public LowCodeJsFileSaveVO save(LowCodeJsFileSaveDTO lowCodeJsFileSaveDTO) throws XbbException {
        LowCodeJsFileSaveVO lowCodeJsFileSaveVO = new LowCodeJsFileSaveVO();
        try {
            String corpid = lowCodeJsFileSaveDTO.getCorpid();
            String userName = lowCodeJsFileSaveDTO.getUserName();
            String formName = lowCodeJsFileSaveDTO.getFormName();
            String userId = lowCodeJsFileSaveDTO.getUserId();
            Long formId = lowCodeJsFileSaveDTO.getFormId();
            Integer whetherToPublish = lowCodeJsFileSaveDTO.getWhetherToPublish();

            // 校验权限
            ProPermissionHelp.verifyPermission(lowCodeJsFileSaveDTO.getLoginUser(), ProPermissionAliasEnum.FORM_SET_UPDATE.getAlias());
            developerService.verifyPermission(corpid, lowCodeJsFileSaveDTO.getFormId(), lowCodeJsFileSaveDTO.getLoginUser(),
                    lowCodeJsFileSaveDTO.getSaasMark(), lowCodeJsFileSaveDTO.getBusinessType());
            if (Objects.isNull(lowCodeJsFileSaveDTO.getFileId())) {

                LowCodeJsFileEntity lowCodeJsFileEntity = new LowCodeJsFileEntity(corpid, lowCodeJsFileSaveDTO.getFormId(), lowCodeJsFileSaveDTO.getSaasMark(), lowCodeJsFileSaveDTO.getBusinessType(),
                        JSON.toJSONString(lowCodeJsFileSaveDTO.getUnreleased()), JSON.toJSONString(lowCodeJsFileSaveDTO.getRelease()), lowCodeJsFileSaveDTO.getWhetherToPublish(), lowCodeJsFileSaveDTO.getUserId());
                lowCodeJsFileModel.insert(lowCodeJsFileEntity);
                lowCodeJsFileSaveVO.setFileId(lowCodeJsFileEntity.getId());
            } else {
                LowCodeJsFileEntity lowCodeJsFileEntity = new LowCodeJsFileEntity(lowCodeJsFileSaveDTO.getFileId(), JSON.toJSONString(lowCodeJsFileSaveDTO.getUnreleased()), lowCodeJsFileSaveDTO.getWhetherToPublish());
                if (Objects.equals(1, lowCodeJsFileSaveDTO.getWhetherToPublish())) {
                    lowCodeJsFileEntity.setPublish(JSON.toJSONString(lowCodeJsFileSaveDTO.getRelease()));
                }
                lowCodeJsFileEntity.setCorpid(corpid);
                lowCodeJsFileModel.update(lowCodeJsFileEntity);
                // 仅发布代码时会打印日志
                if (Objects.equals(1, whetherToPublish)) {
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_RELEASED_LOW_CODE_FORM), userName, formName);
                    mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.LOW_CODE, OperateTypeEnum.LOW_CODE_RELEASE, formId.toString(),
                            formName, memo, lowCodeJsFileSaveDTO.getHttpHeader());
                }
                lowCodeJsFileSaveVO.setFileId(lowCodeJsFileEntity.getId());
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("LowCodeJsFileServiceImpl.save 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return lowCodeJsFileSaveVO;
    }

    @Override
    public LowCodeJsFileGetVO get(LowCodeJsFileGetDTO lowCodeJsFileGetDTO) throws XbbException {
        LowCodeJsFileGetVO lowCodeJsFileGetVO = new LowCodeJsFileGetVO();
        try {
            String corpid = lowCodeJsFileGetDTO.getCorpid();
            // 校验权限
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.FORM_ID, lowCodeJsFileGetDTO.getFormId());
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), lowCodeJsFileGetDTO.getBusinessType())) {
                param.put(StringConstant.BUSINESS_TYPE, lowCodeJsFileGetDTO.getBusinessType());
            }
            List<LowCodeJsFileEntity> fileList = lowCodeJsFileModel.findEntitys(param);
            if (CollectionsUtil.isNotEmpty(fileList)) {
                fileList.forEach(item->{
                    lowCodeJsFileGetVO.setFileId(item.getId());
                    lowCodeJsFileGetVO.setWhetherToPublish(item.getWhetherToPublish());
                    lowCodeJsFileGetVO.setRelease(JSON.parseObject(item.getPublish(), JsFilePojo.class));
                    lowCodeJsFileGetVO.setUnreleased(JSON.parseObject(item.getUnreleased(), JsFilePojo.class));
                });
            }
        } catch (Exception e) {
            LOG.error("LowCodeJsFileServiceImpl.save 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return lowCodeJsFileGetVO;
    }

    @Override
    public LowCodeJsFileGetVO getFileConfig(LowCodeJsFileGetDTO lowCodeJsFileGetDTO) throws XbbException {
        LowCodeJsFileGetVO lowCodeJsFileGetVO = new LowCodeJsFileGetVO();
        try {
            LowCodeConfigGetDTO lowCodeConfigGetDTO = new LowCodeConfigGetDTO();
            lowCodeConfigGetDTO.setCorpid(lowCodeJsFileGetDTO.getCorpid());
            lowCodeConfigGetDTO.setFormId(lowCodeJsFileGetDTO.getFormId());
            lowCodeConfigGetDTO.setBusinessType(lowCodeJsFileGetDTO.getBusinessType());
            lowCodeConfigGetDTO.setLoginUser(lowCodeJsFileGetDTO.getLoginUser());
            LowCodeConfigGetVO lowCodeConfig = lowCodeConfigService.get(lowCodeConfigGetDTO);
            lowCodeJsFileGetVO.setLowCodeConfig(lowCodeConfig);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("LowCodeJsFileServiceImpl.getFileConfig 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return lowCodeJsFileGetVO;
    }
}
